package editor.graphics;

import moltencore.game.loader.LevelSprite;
import editor.logic.LevelSpriteFactory;
import editor.logic.Editor;

import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;

import moltencore.game.bubble.Type;
import spark.math.Vector2;

public class EditorCanvas extends GLCanvas implements MouseListener {
	private Scene scene;
	private Editor editor;
	private Brush brush;
	private Type bubbleBrushType;

	public EditorCanvas(GLCapabilities glCapabilities, Editor editor) {
		super(glCapabilities);
		this.editor = editor;
		addMouseListener(this);
	}

	public void setScene(Scene scene) {
		this.scene = scene;
		scene.addEditor(editor);
		LevelSpriteFactory.levelSpriteFactoryHandler = scene;
		addGLEventListener(scene);
		addKeyListener(scene);
		addMouseMotionListener(scene);
		addMouseWheelListener(scene);
	}

	@Override
	public void mouseClicked(MouseEvent e) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
		if(e.getButton() != MouseEvent.BUTTON1) {
			return;
		}
		LevelSprite cursor = scene.getCursor();
		if(cursor == null) {
			return;
		}
		else if(brush == Brush.Geometry) {
			LevelSprite newSprite = new LevelSprite(cursor);
			editor.stamp(newSprite);
		}
		if(brush == Brush.Bubble) {
			editor.addBubble(bubbleBrushType, scene.getGridPositionX(), scene.getGridPositionY());
		}
		else if(brush == Brush.Next0) {
			editor.setCannonPosition(new Vector2(cursor.getRenderable().getPosition().x, cursor.getRenderable().getPosition().y), 0);
		}
		else if(brush == Brush.Next1) {
			editor.setCannonNextPosition(new Vector2(cursor.getRenderable().getPosition().x, cursor.getRenderable().getPosition().y), 0);
		}
		else if(brush == Brush.HorizontalWall) {
			editor.makeHorizontalWall(cursor.getRenderable().getPosition().y);
		}
		else if(brush == Brush.VerticalWall) {
			editor.makeVerticalWall(cursor.getRenderable().getPosition().x);
		}
		else if(brush == Brush.RestrictedArea) {
			editor.makeRestrictedArea(cursor.getRenderable().getPosition().y);
		}
		else if(brush == Brush.CriticalArea) {
			editor.makeCriticalArea(cursor.getRenderable().getPosition().y);
		}
		else if(brush == Brush.KillArea) {
			editor.makeKillArea(cursor.getRenderable().getPosition().y);
		}
		else if(brush == Brush.Score) {
			editor.setScore(cursor.getRenderable().getPosition().x, cursor.getRenderable().getPosition().y);
		}
		else if(brush == Brush.Nick) {
			editor.setNick(cursor.getRenderable().getPosition().x, cursor.getRenderable().getPosition().y);
		}
		else if(brush == Brush.Clock) {
			editor.setClock(cursor.getRenderable().getPosition().x, cursor.getRenderable().getPosition().y);
		}
		else if(brush == Brush.Result) {
			editor.setResult(cursor.getRenderable().getPosition().x, cursor.getRenderable().getPosition().y);
		}
		else if(brush == Brush.Push) {
			editor.addPush(scene.getGridPositionX(), scene.getGridPositionY());
		}
		else if(brush == Brush.Fill) {
			editor.addFill(scene.getGridPositionX(), scene.getGridPositionY());
		}
	}

	@Override
	public void mouseReleased(MouseEvent e) {
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		setFocusable(true);
		requestFocus();
	}

	@Override
	public void mouseExited(MouseEvent e) {
		setFocusable(false);
	}

	public void doFrame(float elapsedSeconds) {
		scene.doFrame(elapsedSeconds);
	}

	public void setCursor(LevelSprite cursor) {
		scene.setCursor(cursor);
	}

	public Brush getBrush() {
		return brush;
	}

	public void setBrush(Brush brush) {
		this.brush = brush;
		if(brush == Brush.Bubble) {
			scene.setBubbleGridSnap(true);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.Push) {
			scene.setBubbleGridSnap(true);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.Fill) {
			scene.setBubbleGridSnap(true);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.Result) {
			scene.setBubbleGridSnap(true);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.Score) {
			scene.setBubbleGridSnap(false);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.Nick) {
			scene.setBubbleGridSnap(false);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.Clock) {
			scene.setBubbleGridSnap(false);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.VerticalWall || brush == Brush.HorizontalWall) {
			scene.setBubbleGridSnap(false);
			scene.setWallGridSnap(true);
		}
		else if(brush == Brush.CriticalArea) {
			scene.setBubbleGridSnap(false);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.KillArea) {
			scene.setBubbleGridSnap(false);
			scene.setWallGridSnap(false);
		}
		else if(brush == Brush.RestrictedArea) {
			scene.setBubbleGridSnap(false);
			scene.setWallGridSnap(false);
		}
		else {
			scene.setBubbleGridSnap(false);
			scene.setWallGridSnap(false);
		}
	}

	public Type getBubbleBrushType() {
		return bubbleBrushType;
	}

	public void setBubbleBrushType(Type bubbleBrushType) {
		this.bubbleBrushType = bubbleBrushType;
	}

	public void setCursorDepth(float depth) {
		scene.setCursorDepth(depth);
	}

	public void setRenderMisc(boolean render) {
		scene.setRenderMisc(render);
	}

	public void setRenderPush(boolean render) {
		scene.setRenderPush(render);
	}

	public void setRenderFill(boolean render) {
		scene.setRenderFill(render);
	}
}
